package com.oa.common;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.oa.common.result.Result;
import com.oa.common.result.SystemCode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 复合型验证失败执行器
 * @author cuichao
 */
public class ComplexAccessDeniedHandler extends AccessDeniedHandlerImpl {

    private static  final Log logger = LogFactory.getLog(ComplexAccessDeniedHandler.class);

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        String accept = request.getHeader(HttpHeaders.ACCEPT);

        boolean isJsonAccept = StringUtils.hasText(accept) && accept.contains(MediaType.APPLICATION_JSON_VALUE);
        boolean isJsonResponse = StringUtils.hasText(request.getParameter("type")) && "json".equals(request.getParameter("type"));

        if (isJsonAccept || isJsonResponse) {
            if (!response.isCommitted()) {
                response.setStatus(HttpStatus.FORBIDDEN.value());
                response.setCharacterEncoding("UTF-8");
                response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
                Result failure = Result.failure(SystemCode.unauthorized, HttpStatus.FORBIDDEN.getReasonPhrase());
                mapper.writeValue(response.getWriter(), failure);
                return;
            }
            defaultAccessDeniedProcessor(request, response, accessDeniedException);
        }
    }

    private void defaultAccessDeniedProcessor(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        super.handle(request, response, accessDeniedException);
    }

}
